package cc.fs.zhihuapp.utils;

import android.content.Context;
import android.media.MediaCodec;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;

import com.google.android.exoplayer.DefaultLoadControl;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.LoadControl;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import com.google.android.exoplayer.MediaCodecUtil;
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
import com.google.android.exoplayer.chunk.VideoFormatSelectorUtil;
import com.google.android.exoplayer.dash.mpd.MediaPresentationDescriptionParser;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.hls.HlsChunkSource;
import com.google.android.exoplayer.hls.HlsMasterPlaylist;
import com.google.android.exoplayer.hls.HlsPlaylist;
import com.google.android.exoplayer.hls.HlsSampleSource;
import com.google.android.exoplayer.upstream.Allocator;
import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer.upstream.DefaultAllocator;
import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer.upstream.DefaultUriDataSource;
import com.google.android.exoplayer.util.ManifestFetcher;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;


/**
 * Created by fostion on 2015/11/4.
 */
public class MyExoPlayer {

    private Context context;
    private ExoPlayer player;
    //视频和音频渲染器
    private MediaCodecVideoTrackRenderer videoRender;
    private MediaCodecAudioTrackRenderer audioRender;
    private PlayerListener playerListener;
    private Timer timer;
    private boolean isUpdate = true;
    private SurfaceHolder surfaceHolder;

    public MyExoPlayer(Context _context) {
        this.context = _context;
        this.timer = new Timer();
    }

    private void e(String msg) {
        Log.e("- player-  ", msg);
    }

    private TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            if (!isUpdate || player == null || !player.getPlayWhenReady()) {
                return;
            }
            //获取缓冲的位置
            long bufferedPosition = player.getBufferedPosition();
            int bufferedPercentage = player.getBufferedPercentage();
            long currentTime = player.getCurrentPosition();
            long duration = player.getDuration();

            if (playerListener != null) {
                playerListener.onProgress((int) duration, (int) currentTime);
                playerListener.onBuffered((int) bufferedPosition);
            }

        }
    };

    public void playUrl(final String url, final SurfaceHolder surfaceHolder) {
        this.surfaceHolder = surfaceHolder;
        if (player == null) {
            //初始化player
            player = ExoPlayer.Factory.newInstance(2, 1000, 5000);
            player.addListener(new ExoPlayer.Listener() {
                @Override
                public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                    switch (playbackState) {
                        case ExoPlayer.STATE_BUFFERING:
                            if (playerListener != null) {
                                playerListener.onBuffering();
                            }
                            break;
                        case ExoPlayer.STATE_ENDED:
                            if (playerListener != null) {
                                playerListener.onCompletion();
                            }
                            break;
                        case ExoPlayer.STATE_PREPARING:
                            break;

                        case ExoPlayer.STATE_READY:
                            if (playerListener != null) {
                                playerListener.onPrepared();
                            }
                            break;

                    }
                }

                @Override
                public void onPlayWhenReadyCommitted() {

                }

                @Override
                public void onPlayerError(ExoPlaybackException error) {
                    error.printStackTrace();
                }
            });
            //创建视频和音频的渲染器
            final int ALLOCATOR_SIZE = 64 * 1024;
            final int BUFFER_SIZE = 10 * 1024 * 1024;
            final String userAgent = "userAgent";
            Allocator allocator = new DefaultAllocator(ALLOCATOR_SIZE);
//            DataSource dataSource = new DefaultHttpDataSource(userAgent,null);
//            ExtractorSampleSource extractorSampleSource = new ExtractorSampleSource(Uri.parse(url), dataSource, allocator, BUFFER_SIZE);


            //分析hls的url
            MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser();
            DefaultUriDataSource manifestDataSource = new DefaultUriDataSource(context, userAgent);
            ManifestFetcher manifestFetcher = new ManifestFetcher<>(url, manifestDataSource, parser);
            Handler handler = new Handler();
            manifestFetcher.singleLoad(handler.getLooper(), new ManifestFetcher.ManifestCallback() {
                @Override
                public void onSingleManifest(Object manifest) {
                    // Build the renderers
                    int[] variantIndices = null;
                    if (manifest instanceof HlsMasterPlaylist) {
                        HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest;
                        try {
                            variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay(context,masterPlaylist.variants, null, false);
                        } catch (MediaCodecUtil.DecoderQueryException e) {
                            e.printStackTrace();
                        }
                    }
                    LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SIZE));
                    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
                    DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
                    HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, (HlsPlaylist)manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
                    HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SIZE);

                    videoRender = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
                    audioRender = new MediaCodecAudioTrackRenderer(sampleSource);
                    player.prepare(videoRender, audioRender);
                    player.sendMessage(audioRender, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME, 1f);
                    player.sendMessage(videoRender, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surfaceHolder.getSurface());
                    player.setPlayWhenReady(true);
                    //开启定时器定时更新播放器信息
                    timer.schedule(timerTask, 0, 500);
                }

                @Override
                public void onSingleManifestError(IOException e) {

                    e("  "+e.toString());
                    e.printStackTrace();

                }
            });


        }
    }

    public void pause() {
        if (player != null) {
            player.setPlayWhenReady(false);
        }
    }

    public void start() {
        if (player != null) {
            player.setPlayWhenReady(true);
        }
    }

    public void stop() {
        if (player != null) {
            player.stop();
        }
    }

    public boolean isPlaying() {
        if (player != null) {
            return player.getPlayWhenReady();
        }
        return false;
    }

    public void seekTo(long position) {
        if (player != null) {
            player.seekTo(position);
        }
    }

    public void release() {
        if (player != null) {
            pause();
            player.stop();
            //发送信息请求取消更新消息
            player.blockingSendMessage(videoRender, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, null);
            //流渲染器清除
            videoRender = null;
            audioRender = null;
            isUpdate = false;
            timerTask.cancel();
            timer.cancel();
            player.release();
            player = null;
        }
    }

    public void setPlayerListener(PlayerListener _PlayerListener) {
        this.playerListener = _PlayerListener;
    }

    public interface PlayerListener {
        void onPrepared();

        void onBuffering();

        void onBuffered(int buffered);

        void onProgress(int total, int progress);

        void onCompletion();
    }

}
